package pers.sloera.leetcode.editor.cn;

import cn.hutool.core.lang.Assert;

/**
 * 字母板上的路径
 *
 * @author sloera
 * @date 2023-02-12 16:44:07
 */
class AlphabetBoardPath {
    public static void main(String[] args) {
        Solution solution = new AlphabetBoardPath().new Solution();
        String input = "leet";
        System.out.println(solution.alphabetBoardPath(input));
        Assert.isTrue("DDR!UURRR!!DDD!".equals(solution.alphabetBoardPath(input)));
        input = "code";
        System.out.println(solution.alphabetBoardPath(input));
        Assert.isTrue("RR!DDRR!UUL!R!".equals(solution.alphabetBoardPath(input)));
        input = "zdz";
        System.out.println(solution.alphabetBoardPath(input));
        Assert.isTrue("DDDDD!UUUUURRR!DDDDLLLD!".equals(solution.alphabetBoardPath(input)));
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public String alphabetBoardPath(String target) {
            StringBuilder result = new StringBuilder();
            // 用数组是因为方法的返回值只能有一个，其实只需要两个int即可表示
            // 使用二维，来保证lambda中对象的引用不变
            final int[][] lastPosition = {new int[]{0, 0}};
            target.chars().forEach(input -> {
                // 获取待定位字符位置
                int[] position = getPosition(input);
                // 拼接到对应位置的命令
                result.append(getCommand(lastPosition[0], position));
                // 记录当前位置
                lastPosition[0] = position;
            });
            return result.toString();
        }

        // 分别拼接左右和上下的指令
        private String getCommand(int[] lastPosition, int[] position) {
            StringBuilder result = new StringBuilder();
            // 待定位字符为z时，需要先走左右，才能下到第5行
            if (position[0] == 5) {
                // 左右
                result.append(getRowOrColumnCommand(lastPosition, position, 1, "R", "L"));
                // 上下
                result.append(getRowOrColumnCommand(lastPosition, position, 0, "D", "U"));
            } else { // 其余（含上次位置为z），先走上下
                // 上下
                result.append(getRowOrColumnCommand(lastPosition, position, 0, "D", "U"));
                // 左右
                result.append(getRowOrColumnCommand(lastPosition, position, 1, "R", "L"));

            }
            result.append("!");
            return result.toString();
        }

        private String getRowOrColumnCommand(int[] lastPosition, int[] position, int rowOrColumn, String positive, String negative) {
            if (position[rowOrColumn] > lastPosition[rowOrColumn]) {
                return appendCommand(position[rowOrColumn] - lastPosition[rowOrColumn], positive);
            } else {
                return appendCommand(lastPosition[rowOrColumn] - position[rowOrColumn], negative);
            }
        }

        private String appendCommand(int step, String command) {
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < step; i++) {
                result.append(command);
            }
            return result.toString();
        }

        // 字母顺序排列，根据字母值对应的顺序值，可以算出字母对应第几行第几列
        private int[] getPosition(int input) {
            int index = input - 'a';
            int row = index / 5;
            int column = index % 5;
            return new int[]{row, column};
        }
    }
    //leetcode submit region end(Prohibit modification and deletion)

}
